package com.seu.githubcn.controller;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seu.githubcn.config.Result;
import com.seu.githubcn.entity.*;
import com.seu.githubcn.mapper.ManagerMapper;
import com.seu.githubcn.mapper.PullRequestMapper;
import com.seu.githubcn.mapper.RepoMapper;
import com.seu.githubcn.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class PullRequestController {

    @Autowired
    UserMapper userMapper;
    @Autowired
    PullRequestMapper pullRequestMapper;

    @Autowired
    RepoMapper repoMapper;

    @Autowired
    ManagerMapper managerMapper;


    /**
     * 查询与某用户相关的 Pull Request 的信息。
     *
     * @param userIds     用户 ID。
     * @param userModes   PR 与用户的关系。0 为该用户发起的，1 为其他用户向该用户相关的仓库发起的。
     * @param statusModes PR 的状态。0 为全部状态，1 为 open 状态，2 为 close 和 merged 状态。
     * @return 查询结果。
     */
    @GetMapping("/user/pulls")
    public Result<?> getMyPulls(
            @RequestParam(defaultValue = "0") String userIds,
            @RequestParam(defaultValue = "0") String userModes,
            @RequestParam(defaultValue = "0") String statusModes
    ) {
        Integer statusMode=Integer.parseInt(statusModes);
        Integer userMode=Integer.parseInt(userModes);
        Integer userId=Integer.parseInt(userIds);
        List<Integer> acceptedStatus = List.of(switch (statusMode) {
            case 0 -> new Integer[]{
                    PullRequest.Status.OPEN,
                    PullRequest.Status.MERGED,
                    PullRequest.Status.CLOSE
            };
            case 1 -> new Integer[]{
                    PullRequest.Status.OPEN
            };
            case 2 -> new Integer[]{
                    PullRequest.Status.MERGED,
                    PullRequest.Status.CLOSE
            };
            default -> new Integer[]{};
        });

        /// 筛选用户的管理记录
        LambdaQueryWrapper<Manager> managerWrapper = Wrappers
                .<Manager>lambdaQuery()
                .eq(Manager::getManagerId, userId);

        /// 筛选用户拥有或管理的仓库
        LambdaQueryWrapper<Repo> repoWrapper = Wrappers
                .<Repo>lambdaQuery()
                .eq(Repo::getOwnerId, userId)
                .or(managerMapper.exists(managerWrapper),
                        i -> i.in(Repo::getRepoId,
                                managerMapper.selectList(managerWrapper)
                                        .stream()
                                        .map(Manager::getRepoId)
                                        .toArray()));

        LambdaQueryWrapper<PullRequest> resultWrapper = Wrappers
                .<PullRequest>lambdaQuery()
                .func(userMode == 0 || userMode == 1 && repoMapper.exists(repoWrapper),
                        i -> {
                            if (userMode == 0) {
                                i.eq(PullRequest::getMergerId, userId);
                            } else {
                                i.in(PullRequest::getTargetRepoId,
                                        repoMapper.selectList(repoWrapper)
                                                .stream()
                                                .map(Repo::getRepoId)
                                                .toArray());
                            }
                        })
                .and(i -> i.in(PullRequest::getPrStatus, acceptedStatus));

        return new Result<>(200,pullRequestMapper.selectList(resultWrapper),"查询成功!");
    }

    /**
     * 获取与某个仓库相关的 PR。
     *
     * @param pageSize    分页大小，默认值为 10。
     * @param currentPage 当前分页页码，默认为 1。
     * @param repoId      必填。请求 PR 的仓库 ID。
     * @param searchMode  请求 PR 的状态，0 为 open，1 为 close 与 merged，默认为 0。
     * @return 查询结果，以 Page 形式返回。
     */
    @GetMapping("/repo/pulls")
    public Result<?> getRepoPulls(
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(defaultValue = "1") Integer currentPage,
            @RequestParam Integer repoId,
            @RequestParam(defaultValue = "0") Integer searchMode
    ) {
        Page<PullRequest> resultPage = new Page<>(currentPage, pageSize);
        List<Integer> acceptedStatus = List.of(switch (searchMode) {
            case 0 -> new Integer[]{
                    PullRequest.Status.OPEN
            };
            case 1 -> new Integer[]{
                    PullRequest.Status.CLOSE,
                    PullRequest.Status.MERGED
            };
            default -> new Integer[]{};
        });

        Wrapper<PullRequest> resultWrapper = Wrappers
                .<PullRequest>lambdaQuery()
                .in(PullRequest::getPrStatus, acceptedStatus)
                .eq(PullRequest::getTargetRepoId, repoId);

        return Result.success(pullRequestMapper.selectPage(resultPage, resultWrapper));
    }

    /**
     * 新建一个 Pull Request。
     *
     * @param pullRequest {@code PullRequest} 对象，其中 {@code prId} 字段应留空，
     *                    {@code prStatus} 与 {@code hasMerged} 字段的值将被丢弃
     *                    （并重新设置）。
     * @return 新建的结果。
     */
    @PostMapping("/repo/create_pulls")
    public Result<?> createPull(
            @RequestBody PullRequest pullRequest
    ) {
        pullRequest.setPrStatus(PullRequest.Status.OPEN);
        pullRequest.setHasMerged(false);

        pullRequestMapper.insert(pullRequest);
        return Result.success();
    }
    @GetMapping("/pulls/get")
    public Result<?> getMyPr(@RequestParam String prId){
        Integer id= Integer.parseInt(prId);
        PullRequest require =
                pullRequestMapper.selectById(id);
        User poster = userMapper.selectById(require.getMergerId());
        require.setPostName(poster.getUserName());
        return new Result<>(200,require,"查询成功!");
    }
}
